﻿using System.Collections.Generic;
using System.Security.AccessControl;
using System.Linq;

namespace System.IO
{
    public abstract class DirectoryAccessorBase : IDirectoryAccessor
    {
        public abstract IDirectoryInfo GetParent(string path);

        public IDirectoryInfo CreateDirectory(string path)
        {
            return CreateDirectory(path, null);
        }

        public abstract IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity);

        public abstract bool Exists(string path);

        public void SetCreationTime(string path, DateTime creationTime)
        {
            SetCreationTimeUtc(path, creationTime.ToUniversalTime());
        }

        public abstract void SetCreationTimeUtc(string path, DateTime creationTimeUtc);

        public DateTime GetCreationTime(string path)
        {
            return GetCreationTimeUtc(path).ToLocalTime();
        }

        public abstract DateTime GetCreationTimeUtc(string path);

        public void SetLastWriteTime(string path, DateTime lastWriteTime)
        {
            SetLastWriteTimeUtc(path, lastWriteTime.ToUniversalTime());
        }

        public abstract void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc);

        public DateTime GetLastWriteTime(string path)
        {
            return GetLastWriteTimeUtc(path).ToLocalTime();
        }

        public abstract DateTime GetLastWriteTimeUtc(string path);

        public void SetLastAccessTime(string path, DateTime lastAccessTime)
        {
            SetLastAccessTimeUtc(path, lastAccessTime.ToUniversalTime());
        }

        public abstract void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc);

        public DateTime GetLastAccessTime(string path)
        {
            return GetLastAccessTimeUtc(path).ToLocalTime();
        }

        public abstract DateTime GetLastAccessTimeUtc(string path);

        public DirectorySecurity GetAccessControl(string path)
        {
            return GetAccessControl(path, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
        }

        public abstract DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections);

        public abstract void SetAccessControl(string path, DirectorySecurity directorySecurity);

        public string[] GetFiles(string path)
        {
            return GetFiles(path, "*", SearchOption.TopDirectoryOnly);
        }

        public string[] GetFiles(string path, string searchPattern)
        {
            return GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly);
        }

        public string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
        {
            return EnumerateFiles(path, searchPattern, searchOption).ToArray();
        }

        public string[] GetDirectories(string path)
        {
            return GetDirectories(path, "*", SearchOption.TopDirectoryOnly);
        }

        public string[] GetDirectories(string path, string searchPattern)
        {
            return GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
        }

        public string[] GetDirectories(string path, string searchPattern, SearchOption searchOption)
        {
            return EnumerateDirectories(path, searchPattern, searchOption).ToArray();
        }

        public string[] GetFileSystemEntries(string path)
        {
            return GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly);
        }

        public string[] GetFileSystemEntries(string path, string searchPattern)
        {
            return GetFileSystemEntries(path, searchPattern, SearchOption.TopDirectoryOnly);
        }

        public string[] GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption)
        {
            return EnumerateFileSystemEntries(path, searchPattern, searchOption).ToArray();
        }

        public IEnumerable<string> EnumerateDirectories(string path)
        {
            return EnumerateDirectories(path, "*");
        }

        public IEnumerable<string> EnumerateDirectories(string path, string searchPattern)
        {
            return EnumerateDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
        }

        public abstract IEnumerable<string> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption);

        public IEnumerable<string> EnumerateFiles(string path)
        {
            return EnumerateFiles(path, "*");
        }

        public IEnumerable<string> EnumerateFiles(string path, string searchPattern)
        {
            return EnumerateFiles(path, searchPattern, SearchOption.TopDirectoryOnly);
        }

        public abstract IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption);

        public IEnumerable<string> EnumerateFileSystemEntries(string path)
        {
            return EnumerateFileSystemEntries(path, "*");
        }

        public IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern)
        {
            return EnumerateFileSystemEntries(path, searchPattern, SearchOption.TopDirectoryOnly);
        }

        public abstract IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern,
                                                                       SearchOption searchOption);

        public abstract string[] GetLogicalDrives();

        public abstract string GetDirectoryRoot(string path);

        public abstract string GetCurrentDirectory();

        public abstract void SetCurrentDirectory(string path);

        public abstract void Move(string sourceDirName, string destDirName);

        public void Delete(string path)
        {
            Delete(path, false);
        }

        public abstract void Delete(string path, bool recursive);
    }
}